package cn.yuanqiao.cqbc.util;
/**
 * @author 赵常飞
 * @date 2024/6/17 13:11
 */
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.SnowflakeIdGenerator;
import cn.yuanqiao.cqbc.common.mapper.MapperToolsMapper;
import cn.yuanqiao.cqbc.dataManage.domain.DataManage;
import cn.yuanqiao.cqbc.dataManageTreePath.domain.InsertEntity;
import com.alibaba.fastjson2.JSONArray;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.io.FileUtils;
import org.mozilla.universalchardet.UniversalDetector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;

/**
 *@Author: 赵常飞
 *@Date: 2024/6/17 13:11
 *@Description:
 *@Note:
 */
@RestController
@RequestMapping("/eeputil")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class EEPUtil {

    @Value("${HD_EEP_PATH}")
    private String hdEepPath;

    @Value("${HD_DA_FILE_PATH}")
    private String hddaFilePath;

    @Resource
    MapperToolsMapper DbTool;

    /**
     * 导入EEP包
     * @return
     * @throws Exception
     */
    public JSONObject receiveEEPPackeg(Map<String,Object> map, String eepPath, DataManage dataManage) throws Exception {
        System.out.println("开始接收");
        //解压缩EEP后存放文件路径
        String zipPath =  hdEepPath+"/JS/";

        zipPath += UUID.randomUUID();
        ZipUtils.unzip(eepPath, zipPath);
        JSONObject msg = new JSONObject();
        traverseFiles(new File(zipPath),map,msg);
        return msg;
    }

    private void traverseFiles(File directory,Map map,JSONObject msg) throws Exception {
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    traverseFiles(file,  map, msg);
                }
            }
        } else {
            //文件类型
            if (directory.getName().toLowerCase().endsWith(".xml")) {
                analysisArchive(directory,map,msg);
            }
        }
    }

    private void analysisArchive(File xmlFile, Map transfermap, JSONObject msg) throws Exception {
        JSONObject archiveData = startXMLToJSON(xmlFile);  //xml 文件解析成 JSON格式
        String tenantCode=String.valueOf(transfermap.get("tenantCode"));
        String categoryId=String.valueOf(transfermap.get("categoryId"));
        String pathId=String.valueOf(transfermap.get("pathId"));
        Long itemId = SnowflakeIdGenerator.generateId();
        Map<String,Object> categoryInfo= DbTool.getMapResult("select ID,PARENT_ID,GROUP_ID,NAME,TYPE,STORE_TYPE,STORE_MODE,CODE,REMARK,ITEM_TABLE_NAME,FOLDER_TABLE_NAME,FILE_TABLE_NAME,EFILE_TABLE_NAME,IS_DEL,CREATE_ID,CREATE_BY,CREATE_TIME,FONDS_CODE,FILE_TYPES,ORDER_NO from "+tenantCode+"_CATEGORY where id="+categoryId);
        List<Map<String,Object>> mdataLists = DbTool.getListResult("select ID, GROUP_ID, FIELD_CAPTION, FIELD_NAME, PROPERTY_NAME, FIELDTYPE, DATA_LENGTH, IS_INPUT, IS_UPDATE, IS_QUERY, IS_ARCHIVE_NO, IS_SYSTEM, IS_NO_EMPTY,\n" +
                "         DEFAULT_VALUE, IS_HIDDEN, REMARK, IS_EXPORT, EXPORT_COLUMN_NAME, EXPORT_ORDER_NO, CREATOR_ID, CREATE_TIME, COL_WIDTH, TH_WIDTH, TH_ALIGN, TYPE, ORDER_NO,\n" +
                "         SHOWTYPE, IS_METADATA, BIANHAO, ENGLISH_NAME, DEFINITION, PURPOSE, CONSTRAINTS, REPEAT_STRING, ELEMENT_TYPE, DATA_TYPE, CODE, RANGE, DEFAULTVALUE, SOURCES,\n" +
                "          NOTES, MD_ORDER_NO, MD_LEVEL, IS_CATALOGUE, CATALOGUE_ORDER, IS_XMLTITLE, ZSFL, CHECK_SPECIAL_CHARACTERS, CHECK_ARCHIVAL_CODE, CHECK_NOEMPTY,\n" +
                "          CHECK_CHONGFU, IS_IMPORT,RELATE_BIANHAO,ZIBIANHAO,SPECIAL_CHARACTER  from "+tenantCode+"_MDATA_LIST where group_id=(select group_id from "+tenantCode+"_CATEGORY where id="+categoryInfo.get("ID")+")");
        if(categoryInfo!= null){
            if ("3".equals(String.valueOf(categoryInfo.get("TYPE")))) {
                //项目层入库

                JSONObject xmJson = archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("内容描述")
                        .getJSONObject("项目层");
                Map<String, String> map = new HashMap<>();
                for (Map<String,Object> mdataList : mdataLists) {
                    if ("3".equals(String.valueOf(mdataList.get("TYPE"))) && xmJson.containsKey(String.valueOf(mdataList.get("FIELD_CAPTION")))) {
                        if ("5".equals(String.valueOf(mdataList.get("SHOWTYPE")))) {
                            map.put(String.valueOf(mdataList.get("FIELD_NAME")), getDictVal(String.valueOf(mdataList.get("FIELD_CAPTION")), xmJson.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))),tenantCode));
                        } else {
                            map.put(String.valueOf(mdataList.get("FIELD_NAME")), xmJson.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))));
                        }
                    }
                }
                map.put("STATE", "9");
                map.put("IS_DEL", "0");
                //map.put("JS_TYPE", "2");

                map.put("CATEGORY_ID", categoryId);
                map.put("DATA_ID", String.valueOf(transfermap.get("data_id")));
                map.put("TENANT_CODE", tenantCode);
                map.put("EEP_PATH", String.valueOf(transfermap.get("path")));
                map.put("EEP_PATH_ID", pathId);
                map.put("EEP_NAME",String.valueOf(transfermap.get("name")));
                //查询是否已有这个项目
                Long oldId = DbTool.getIdByMap(map,tenantCode+"_CQBC_ITEM");
                if (oldId == null) {
                    map.put("ITEM_ID", String.valueOf(itemId));
                    InsertEntity yqItem = new InsertEntity();
                    yqItem.setColNames(map);
                    yqItem.setTableName(tenantCode+"_CQBC_ITEM");
                    DbTool.insertEntity(yqItem);
                } else {
                    itemId = oldId;
                }
            }
            //处理卷层
            Long folderId = SnowflakeIdGenerator.generateId();
            if ("3".equals(String.valueOf(categoryInfo.get("TYPE"))) || "1".equals(String.valueOf(categoryInfo.get("TYPE")))) {
                JSONObject juanJson = archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("内容描述");
                Map<String, String> map = new HashMap<>();
                for (Map<String,Object> mdataList : mdataLists) {
                    if ("1".equals(String.valueOf(mdataList.get("TYPE"))) && juanJson.containsKey(String.valueOf(mdataList.get("FIELD_CAPTION")))) {
                        if ("5".equals(String.valueOf(mdataList.get("SHOWTYPE")))) {
                            map.put(String.valueOf(mdataList.get("FIELD_NAME")), getDictVal(String.valueOf(mdataList.get("FIELD_NAME")), juanJson.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))),tenantCode));
                        } else {
                            map.put(String.valueOf(mdataList.get("FIELD_NAME")), juanJson.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))));
                        }
                    }
                }
                map.put("STATE", "9");
                map.put("IS_DEL", "0");
                //map.put("JS_TYPE", "2");
                map.put("FOLDER_ID", String.valueOf(folderId));

                map.put("CATEGORY_ID", categoryId);
                map.put("DATA_ID", String.valueOf(transfermap.get("data_id")));
                map.put("TENANT_CODE", tenantCode);
                map.put("EEP_PATH", String.valueOf(transfermap.get("path")));
                map.put("EEP_PATH_ID", pathId);
                map.put("EEP_NAME",String.valueOf(transfermap.get("name")));

                InsertEntity yqFolder = new InsertEntity();
                yqFolder.setTableName(tenantCode+"_CQBC_FOLDER");
                yqFolder.setColNames(map);
                DbTool.insertEntity(yqFolder);

                //添加关联关系
                if ("3".equals(String.valueOf(categoryInfo.get("TYPE")))) {
                    InsertEntity itemFolder = new InsertEntity();
                    Map itemFoldermap=new HashMap(1<<1);
                    itemFoldermap.put("FOLDER_ID",folderId);
                    itemFoldermap.put("ITEM_ID",itemId);
                    itemFolder.setTableName(tenantCode+"_CQBC_ITEM_FOLDER");
                    itemFolder.setColNames(itemFoldermap);
                    DbTool.insertEntity(itemFolder);
                }
            }
            //处理件层
            JSONArray jianArray = new JSONArray();
            if ("0".equals(String.valueOf(categoryInfo.get("TYPE")))) {
                jianArray.add(archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("内容描述"));
            } else {
                jianArray = archiveData.getJSONObject("被签名对象").getJSONObject("封装内容").getJSONObject("档案实体块").getJSONObject("内容描述").getJSONObject("件层集").getJSONArray("件层");
            }

            String baseDir = hddaFilePath; //保存位置
            for (int i = 0; i < jianArray.size(); i++) {
                JSONObject jian = jianArray.getJSONObject(i);
                Long daId = SnowflakeIdGenerator.generateId();
                Map<String, String> map = new HashMap<>();
                for (Map<String,Object> mdataList : mdataLists) {
                    if ("0".equals(String.valueOf(mdataList.get("TYPE"))) && jian.containsKey(String.valueOf(mdataList.get("FIELD_CAPTION")))) {
                        if ("5".equals(String.valueOf(mdataList.get("SHOWTYPE")))) {
                            map.put(String.valueOf(mdataList.get("FIELD_NAME")), getDictVal(String.valueOf(mdataList.get("FIELD_NAME")), jian.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))),tenantCode));
                        } else {
                            map.put(String.valueOf(mdataList.get("FIELD_NAME")), jian.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))));
                        }
                    }
                }

                if (null == map.get("DH") || map.get("DH").length() <= 0) {
                    throw new ServiceException("四性检测完成，但件层缺少“DH”字段！");
                }
                String jianDH = map.get("DH");
                map.put("STATE", "9");
                map.put("IS_DEL", "0");
                //map.put("JS_TYPE", "2");
                map.put("DA_ID", String.valueOf(daId));

                map.put("CATEGORY_ID", categoryId);
                map.put("DATA_ID", String.valueOf(transfermap.get("data_id")));
                map.put("TENANT_CODE", tenantCode);
                map.put("EEP_PATH", String.valueOf(transfermap.get("path")));
                map.put("EEP_PATH_ID", pathId);
                map.put("EEP_NAME",String.valueOf(transfermap.get("name")));

                InsertEntity yqda = new InsertEntity();
                yqda.setColNames(map);
                yqda.setTableName(tenantCode+"_CQBC_HDDA");
                DbTool.insertEntity(yqda);

                //添加关联关系
                if (!"0".equals(String.valueOf(categoryInfo.get("TYPE")))) {
                    InsertEntity yqdaFolder = new InsertEntity();
                    Map yqdaFoldermap=new HashMap(1<<1);
                    yqdaFoldermap.put("DA_ID",daId);
                    yqdaFoldermap.put("FOLDER_ID",folderId);
                    yqdaFolder.setTableName(tenantCode+"_CQBC_DA_FOLDER");
                    yqdaFolder.setColNames(yqdaFoldermap);
                    DbTool.insertEntity(yqdaFolder);
                }

                //解析电子文件层
                JSONArray eFileJson = null;
                /*if(category.getType() !=0){
                    eFileJson = jian.getJSONObject("文件数据集").getJSONArray("文件数据");
                }else {
                    eFileJson = jian.getJSONObject("文件数据集").getJSONArray("文件数据");
                }*/
                if (jian.getJSONObject("文件数据集") != null) {
                    eFileJson = objecttoarray(jian.getJSONObject("文件数据集").get("文件数据"));
                    for (int j = 0; j < eFileJson.size(); j++) {
                        JSONObject eFileObject = eFileJson.getJSONObject(j).getJSONObject("文档").getJSONObject("文档数据").getJSONObject("编码").getJSONObject("电子属性");
                        map = new HashMap<>();
                        for (Map<String,Object> mdataList : mdataLists) {
                            if ("2".equals(String.valueOf(mdataList.get("TYPE"))) && eFileObject.containsKey(String.valueOf(mdataList.get("FIELD_CAPTION")))) {
                                if ("5".equals(String.valueOf(mdataList.get("SHOWTYPE")))) {
                                    map.put(String.valueOf(mdataList.get("FIELD_NAME")), getDictVal(String.valueOf(mdataList.get("FIELD_NAME")), eFileObject.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))),tenantCode));
                                } else {
                                    map.put(String.valueOf(mdataList.get("FIELD_NAME")), eFileObject.getString(String.valueOf(mdataList.get("FIELD_CAPTION"))));
                                }
                            }
                        }
                        String filePath = new StringBuilder().append(categoryInfo.get("FONDS_CODE")).append(File.separator).append(categoryId).append(File.separator).
                                append(daId).append(File.separator).toString();
                        String fileName = eFileObject.getString("文件实际名称");
                        if (!eFileObject.containsKey("文件实际名称")) {
                            throw new ServiceException("四性检测完成，但电子件层缺少“文件实际名称”！");
                        }
                        if (!eFileObject.containsKey("文件类型")) {
                            throw new ServiceException("四性检测完成，但电子件层缺少“文件类型”！");
                        }
                        File xmlPath = null;
                        if (!"0".equals(String.valueOf(categoryInfo.get("TYPE")))) {
                            xmlPath = new File(xmlFile.getParent() + File.separator + jianDH + File.separator + fileName);  //归档包电子文件路径
                        } else {
                            xmlPath = new File(xmlFile.getParent() + File.separator + fileName);  //归档包电子文件路径
                        }
                        String absPath = getAbsoluteFile(baseDir + filePath, fileName).getAbsolutePath();  //保存文件位置  绝对路径
                        FileUtils.copyFile(xmlPath, new File(absPath));  //复制文件
                        map.put("PATH", filePath + fileName);
                        map.put("DOC_MNT", baseDir);
                        map.put("IS_INDEX", "0");
                        map.put("IS_DEL", "0");
                        map.put("CON_TABLE_ID",String.valueOf(daId));
                        map.put("DOC_ID",String.valueOf(SnowflakeIdGenerator.generateId()));
                        map.remove("CREATE_BY");
                        InsertEntity saveDocument = new InsertEntity();
                        saveDocument.setColNames(map);
                        saveDocument.setTableName(tenantCode+"_CQBC_HDDADOCUMENT");
                        DbTool.insertEntity(saveDocument);
                    }
                }
            }
        } else {
            msg.put("msg", "没有匹配到门类信息！");
        }
    }

    private JSONArray objecttoarray(Object object) {
        if(object instanceof JSONObject){
            JSONArray array=new JSONArray(1);
            array.add(object);
            return array;
        }else if(object instanceof JSONArray){
            return (JSONArray)object;
        }
        return null;
    }

    public static JSONObject startXMLToJSON(File path) throws Exception{
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path))) {
            UniversalDetector detector = new UniversalDetector(null);
            byte[] buf = new byte[4096];
            int nread;

            while ((nread = bis.read(buf)) > 0 && !detector.isDone()) {
                detector.handleData(buf, 0, nread);
            }

            detector.dataEnd();
            //读取txt文件的编码格式
            String encoding = detector.getDetectedCharset();
            detector.reset();
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), encoding))) {
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                    sb.append(System.lineSeparator());
                }
                String xml = sb.toString();
                XmlMapper xmlMapper = new XmlMapper();
                ObjectMapper objectMapper = new ObjectMapper();
                Object xmlObject = xmlMapper.readValue(xml, Object.class);
                return JSONObject.parseObject(objectMapper.writeValueAsString(xmlObject));
            }
        }
    }

    private String getDictVal(String fieldName, String dict,String tenantCode) {
        String DictVal = "";
        Boolean bl = false;
        List<Map<String,Object>> list = DbTool.getListResult("select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark from "+tenantCode+"_DICT_DATA where status = '0' and dict_type = '"+fieldName+"' order by dict_sort asc");
        if (list != null && list.size() > 0) {
            if (dict != null) {
                for (Map<String,Object> dictData : list) {
                    if (dict.equals(String.valueOf(dictData.get("DICT_LABEL")))) {
                        DictVal = String.valueOf(dictData.get("DICT_VALUE"));
                        bl = true;
                        break;
                    }
                }
            }
            if (!bl) {
                DictVal = dict;
            }
        } else {
            DictVal = dict;
        }

        return DictVal;
    }
    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File desc = new File(uploadDir + File.separator + fileName);

        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                desc.getParentFile().mkdirs();
            }
        }
        return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
    }
}
